import { Hono } from 'hono';
import { HonoContext } from '../types/hono';
import { User } from '../types/db';
import { AppError } from '../utils/error';
import { ReturnResponse } from '../utils/response';
import { generateToken } from '../handlers/auth';
import * as cryptor from '../utils/cryptor';

const router = new Hono();

router.post("/register", async (c: HonoContext) => {
    const { username, password, email } = await c.req.json();

    if (!email) {
        throw new AppError("email is required");
    }

    if (!username || !password) {
        throw new AppError("Username and password are required");
    }

    const existingUser = await c.env.DB.prepare(
        'SELECT id FROM users WHERE username = ?'
    ).bind(username).first();

    if (existingUser) {
        throw new AppError("Username already exists");
    }

    const passwordHash = await cryptor.sha256(password, c.env.PASSWORD_SALT);
    await c.env.DB.prepare(
        'INSERT INTO users (username, password_hash, email) VALUES (?, ?, ?)'
    ).bind(username, passwordHash, email || null).run();

    return c.json(ReturnResponse.success());
});

router.post("/login", async (c: HonoContext) => {
    const { username, password } = await c.req.json();

    if (!username || !password) {
        throw new AppError("Username and password are required");
    }

    const user = await c.env.DB.prepare(
        'SELECT * FROM users WHERE username = ?'
    ).bind(username).first<User>();

    if (!user) {
        throw new AppError("Invalid username or password");
    }

    const valid = await cryptor.sha256Compare(password, user.password_hash, c.env.PASSWORD_SALT);
    if (!valid) {
        throw new AppError("Invalid username or password");
    }

    const token = await generateToken(c, user.id);
    return c.json(ReturnResponse.success(token));
});

export default router;